/*
 * @Author: xiaosihan
 * @Date: 2024-06-20 21:38:49
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-06-21 12:59:04
 */

// 爆炸模型对象
import homeStore from "@views/home/homeStore";
import { round } from "lodash";
import { Group, AxesHelper, Vector3, Mesh, MeshBasicMaterial, DoubleSide } from "three";
import threeLoader from "three-base/threeLoader";
import threeUtils from "three-base/threeUtils";
import metalMaterial from "../publicMaterial/metalMaterial";
import utils from "@utils";
import { BlobOptions } from "buffer";

// 爆炸模型
export default class BlastMesh extends Group {
    constructor() {
        super();
    }

    // 把需要爆炸的模型放到这个组里面
    blastGroup = (() => {
        const blastGroup = new Group();
        this.add(blastGroup);
        return blastGroup;
    })();

    //保存每个模型对象的爆炸方向
    blastDirection: Map<string, Vector3> = new Map();

    //加载模型
    async loadModal(url: string = "") {

        if (!url) {
            return;
        }

        const mesh = await threeLoader.loadModal(url);

        //清空对象爆炸方向
        this.blastDirection.clear();

        //清空爆炸组
        this.blastGroup.clear();

        //缩放到制定大小
        threeUtils.scaleTo(mesh, 5);

        // 对象先居中显示
        threeUtils.center(mesh);

        //模型数组
        const meshs: Array<Mesh> = [];

        //把模型都放到爆炸组里
        mesh.traverse(o => {
            const m = o as Mesh;
            if (m.isMesh) {
                //网格模型应用世界矩阵
                m.geometry.applyMatrix4(m.matrixWorld);
                m.position.set(0, 0, 0);
                m.scale.set(1, 1, 1);
                m.rotation.set(0, 0, 0);

                // 都换成金属材质
                m.material = metalMaterial;

                // 记录网格模型的中心点为初始方向向量
                const center = threeUtils.getCenter(m.geometry);
                this.blastDirection.set(m.uuid, center);

                //把模型对象加入爆炸组,方便操作
                meshs.push(m);

                //添加模型的点击事件
                m.userData = {
                    cursor: "pointer",
                    enableEvent: true,
                    stroke_enable: false,//启用描边
                    stroke_color: "#04fa12",//描边颜色
                    stroke_width: 3,//描边厚度(像素)
                };
                m.addEventListener("click", e => {
                    homeStore.setActiveId(m.uuid);
                    homeStore.setActiveName(m.name);
                    const size = threeUtils.getSize(m);
                    homeStore.setActiveSize({ x: round(size.x, 2), y: round(size.y, 2), z: round(size.z, 2) });
                    const position = threeUtils.getCenter(m);
                    homeStore.setActivePosition({ x: round(position.x, 2), y: round(position.y, 2), z: round(position.z, 2) });
                });
            }
        });

        this.blastGroup.add(...meshs);

        //加载完成事件
        this.dispatchEvent({ type: "loaded" } as never);

        //更新爆炸进度
        this.setBlastProgress(this.blastProgress);
    }

    // 爆炸进度
    blastProgress = 0;

    // 设置爆炸进度
    setBlastProgress(blastProgress: number) {
        this.blastProgress = blastProgress;
        this.blastGroup.traverse(o => {
            //根据爆炸进度和爆炸方向计算模型的位置
            const center = this.blastDirection.get(o.uuid);
            if (center) {
                o.position.copy(center).multiplyScalar(this.blastProgress);
            }
        })
    }

    //设置高亮
    setStroke(id: string) {
        this.blastGroup.traverse(o => {
            Object.assign(o.userData, {
                stroke_enable: (o.uuid === id)//启用描边
            })
        })
    }

    //仅显示选中模型
    onlyShow(isOnlyShow: boolean, id: string = "") {
        this.blastGroup.children.map(o => {
            o.visible = isOnlyShow ? (o.uuid === id) : true;
        });
    }

}